package com.xhx.controller;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.multipart.MultipartFile;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.IORuntimeException;

/**
 * pdf转pic-抽象类
 *
 * @author xhx
 */
public abstract class AbstractPdfPictureController extends AbstractPdfController {
	private static final String IMAGETYPE_JPG = "jpg";

	protected ThreadPoolTaskExecutor executor;

	public AbstractPdfPictureController(ThreadPoolTaskExecutor executor, Logger log) {
		super(log);
		this.executor = executor;
	}

	protected String getFileName(File file) {
		return file.getName().replace(".pdf", "");
	}

	protected String getFileName(MultipartFile file) {
		return file.getOriginalFilename().replace(".pdf", "");
	}

	protected String getDir(File file) {
		return file.getAbsolutePath().replace(file.getName(), "");
	}

	protected boolean checkPage(int total, Integer index) {
		return index >= 0 && index < total;
	}

	/**
	 * 拆分pdf成图片到文件
	 * 
	 * @param outputDirPath
	 * @param fileName
	 * @param pdfRenderer
	 * @param page
	 * @param dpi
	 */
	protected void split(String outputDirPath, String fileName, PDFRenderer pdfRenderer, int page, Integer dpi) {
		BufferedImage bim = null;
		try {
			bim = pdfRenderer.renderImageWithDPI(page, dpi, ImageType.RGB);
			File outputFile = new File(outputDirPath + fileName);
			ImageIO.write(bim, IMAGETYPE_JPG, outputFile);
			log.info("结束处理-{}", fileName);
		} catch (Exception e) {
			log.info("处理失败-{},{}", fileName, e.getMessage(), e);
		} finally {
			if (null != bim) {
				bim.flush();
			}
		}
	}

	protected void merge(String outputDirPath, String fileName, BufferedImage firstPageImage,
			BufferedImage secondPageImage) {
		int width = firstPageImage.getWidth() + secondPageImage.getWidth();
		int height = Math.max(firstPageImage.getHeight(), secondPageImage.getHeight());
		BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = combined.getGraphics();
		g.drawImage(firstPageImage, 0, 0, null);
		g.drawImage(secondPageImage, firstPageImage.getWidth(), 0, null);

		File outputFile = new File(outputDirPath + fileName);
		ImgUtil.write(combined, outputFile);
		g.dispose();
		log.info("结束处理-{}", fileName);
	}

	/**
	 * 使用线程池批量执行任务
	 * 
	 * @param <T>
	 * @param tasks
	 * @return
	 */
	protected <T> Integer asyncTask(Collection<Supplier<T>> tasks) {
		int n = tasks.size();
		CountDownLatch latch = new CountDownLatch(n);

		for (Supplier<T> t : tasks) {
			this.executor.execute(() -> {
				t.get();
				latch.countDown();
			});
		}

		try {
			latch.await(1, TimeUnit.HOURS);
		} catch (InterruptedException e) {
			log.error(e.getMessage(), e);
		}
		return n;
	}

	/**
	 * 输出图片到返回流
	 * 
	 * @param fileName
	 * @param firstPageImage
	 * @param secondPageImage
	 * @param response
	 * @throws IORuntimeException
	 * @throws IOException
	 */
	protected void getMerge(String fileName, BufferedImage firstPageImage, BufferedImage secondPageImage,
			HttpServletResponse response) throws IORuntimeException, IOException {
		// 设置响应内容类型
		response.setContentType("image/jpg"); // 根据需要设置正确的MIME类型
		int width = firstPageImage.getWidth() + secondPageImage.getWidth();
		int height = Math.max(firstPageImage.getHeight(), secondPageImage.getHeight());
		BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = combined.getGraphics();
		g.drawImage(firstPageImage, 0, 0, null);
		g.drawImage(secondPageImage, firstPageImage.getWidth(), 0, null);

		ImgUtil.write(combined, IMAGETYPE_JPG, response.getOutputStream());
		g.dispose();
		log.info("结束处理-{}", fileName);
	}

	protected void preview(String fileName, BufferedImage image, HttpServletResponse response) throws IOException {
		// 设置响应内容类型
		response.setContentType("image/jpg"); // 根据需要设置正确的MIME类型
		ImageIO.write(image, IMAGETYPE_JPG, response.getOutputStream());
		log.info("结束处理-{}", fileName);
	}

}
